package com.lyn.seckill.service.impl;

import com.lyn.seckill.common.error.BusinessException;
import com.lyn.seckill.common.error.EnumBusinessError;
import com.lyn.seckill.dao.ItemDoMapper;
import com.lyn.seckill.dao.ItemStockDoMapper;
import com.lyn.seckill.dataobject.ItemDo;
import com.lyn.seckill.dataobject.ItemStockDo;
import com.lyn.seckill.service.ItemService;
import com.lyn.seckill.service.PromoService;
import com.lyn.seckill.service.model.ItemModel;
import com.lyn.seckill.service.model.PromoModel;
import com.lyn.seckill.validator.ValidationResult;
import com.lyn.seckill.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    private final ItemDoMapper itemDoMapper;
    private final ItemStockDoMapper itemStockDoMapper;
    private final ValidatorImpl validator;
    private final PromoService promoService;
    @Autowired
    public ItemServiceImpl(ItemDoMapper itemDoMapper, ItemStockDoMapper itemStockDoMapper, ValidatorImpl validator, PromoService promoService) {
        this.itemDoMapper = itemDoMapper;
        this.itemStockDoMapper = itemStockDoMapper;
        this.validator = validator;
        this.promoService = promoService;
    }

    /**
     * 创建商品
     * @param itemModel
     * @return
     * @throws BusinessException
     */
    @Override
    @Transactional
    public ItemModel createItem(ItemModel itemModel) throws BusinessException {
        // 入参校验
        ValidationResult validate = validator.validate(itemModel);
        if (validate.isHasError()) {
            throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR,validate.getErrorMessage());
        }
        // 转化模型MO->DO
        ItemDo itemDo = this.convertItemDoFromItemModel(itemModel);

        // 写入数据库
        itemDoMapper.insertSelective(itemDo);
        itemModel.setId(itemDo.getId());
        ItemStockDo itemStockDo = this.convertItemStockDoFromItemModel(itemModel);
        itemStockDoMapper.insertSelective(itemStockDo);
        // 返回创建完成的对象
        return this.getItemById(itemModel.getId());
    }

    /**
     * 获取商品集合
     * @return
     */
    @Override
    public List<ItemModel> listItem() {
        List<ItemDo> itemDos = itemDoMapper.selectList();
        return itemDos.stream().map(itemDo -> {
            ItemStockDo itemStockDo = itemStockDoMapper.selectByItemId(itemDo.getId());
            ItemModel itemModel = this.convertModelFromDataObject(itemDo, itemStockDo);
            return itemModel;
        }).collect(Collectors.toList());
    }

    /**
     * 获取商品信息
     * @param id
     * @return
     */
    @Override
    public ItemModel getItemById(Integer id) {
        ItemDo itemDo = itemDoMapper.selectByPrimaryKey(id);
        if (itemDo == null) {
            return null;
        }
        // 操作获取库存的数量
        ItemStockDo itemStockDo = itemStockDoMapper.selectByItemId(itemDo.getId());
        // 将DO->MO
        ItemModel itemModel = this.convertModelFromDataObject(itemDo, itemStockDo);

        // 获取活动商品的信息
        PromoModel promoByItemId = promoService.getPromoByItemId(itemModel.getId());
        if (promoByItemId != null && promoByItemId.getStatus().intValue() != EnumBusinessError.PROMO_FINISHED) {
            itemModel.setPromoModel(promoByItemId);
        }
        return itemModel;
    }

    @Override
    public boolean decreaseStock(Integer itemId, Integer amount) {
        int i = itemStockDoMapper.decreaseStock(itemId, amount);
        if (i > 0) {
            // 更新库存成功
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public void increaseSales(Integer itemId, Integer amount) {
        itemDoMapper.increaseSales(itemId,amount);
    }

    private ItemDo convertItemDoFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemDo itemDo = new ItemDo();
        BeanUtils.copyProperties(itemModel,itemDo);
        itemDo.setPrice(itemModel.getPrice().doubleValue());
        return itemDo;
    }

    private ItemStockDo convertItemStockDoFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemStockDo itemStockDo = new ItemStockDo();
        itemStockDo.setItemId(itemModel.getId());
        itemStockDo.setStock(itemModel.getStock());
        return itemStockDo;
    }

    private ItemModel convertModelFromDataObject(ItemDo itemDo,ItemStockDo itemStockDo) {
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(itemDo,itemModel);
        itemModel.setPrice(new BigDecimal(itemDo.getPrice()));

        itemModel.setStock(itemStockDo.getStock());
        return itemModel;
    }

}
